from datetime import datetime, date, timedelta
import re
import time
import pandas as pd
import tushare as ts
import numpy as np
from funcat import *
import requests
import talib as tb
import other
import random
import functools
import sys
"""
#————————————————————————————————————————————————————————————
成交量预测：返回系数V_predict()，和时间有关
成交量预测：返回df V_predict_data(data)，和时间有关
#————————————————————————————————————————————————————————————
开始结束时间：time_start(days=20,dtype="no-") 
时间防止：len_fangzhi(start_time, today_time)->return len(time_), time_[0], time_[1]
时间个股防止：len_fangzhi_szcode(szcode, start_time, today_time)->len(time_)
funcat_time时间：funcat_time()->return _funcat_time, len_time
周六time_zhou6_0
#————————————————————————————————————————————————————————————
re正则code  gu_zhengze_sz(code)
读取正则re_read_df
读取文件
#————————————————————————————————————————————————————————————
进度条
运行#_write_console
progress_bar(i,num1=1,num2=2)

"""

global pro  # 在使用前初次声明
ts.set_token('b31e0ac207a5a45e0f7503aff25bf6bd929b88fe1d017a034ee0d530')
pro = ts.pro_api()

#————————————————————————————————————————————————————————————
def V_predict():
    """
    当日成交量预测
    1）根据时间计算今日时长
    2）根据V*4/时长
    3）返回时间比例
    """
    time_day_ = time.localtime(
        time.time())  # time.struct_time(tm_year=2020, tm_mon=10, tm_mday=30, tm_hour=15, tm_min=4, tm_sec=15, tm_wday=4, tm_yday=304, tm_isdst=0)
    time_bili = time_day_.tm_hour - 9.5 + time_day_.tm_min / 60  # 15:06 ----->5.6
    if 0 < time_bili <= 2:  # 上午九点半到11点半
        time_day_time = time_bili
    if 2 < time_bili <= 3.5:  # 中午11点半到1点
        time_day_time = 2
    if 3.5 < time_bili <= 5.5:  # 下午一点到3点
        time_day_time = time_bili - 1.5
    if 5.5 < time_bili or time_bili <= 0:  # 下午3点以后 #上午九点半前
        time_day_time = 4
    time_day_timepass = round(4 / time_day_time, 2)  # 时间系数
    # 5.6 数字
    return time_day_timepass
def V_predict_data(data):#rq使用
    """
    """
    time_day_timepass = V_predict()
    # print("现在时间{}:{},{}倍系数".format(time_day_.tm_hour,time_day_.tm_min,time_day_timepass))
    data["volume_predict"] = data["volume"] * time_day_timepass
    data["turnoverratio_predict"] = data["turnoverratio"] * time_day_timepass
    data["amount_predict"] = data["amount"] * time_day_timepass
    return data
#————————————————————————————————————————————————————————————
# __ma120
def time_start(days=20,dtype="no-"):
    """今天时间today_time 格式20200307
    开始时间start_time 格式20191108
    start_time, today_time, _hour_= other.time_start(dtype="with-")
    dtype=="no-" 不带-
         =="with-" 带-
    :return ('20211031', '20211120', '11:58')"""
    _today_time = str(datetime.now())[:11]  # 2020-10-30 14:08:54.158185 ----->2020-10-30
    _start_time = str(datetime.now() - timedelta(days))[:11]  # 2020-10-10 14:10:33.700162
    today_time = re.sub(r'\D', "", _today_time)  # 20201030
    start_time = re.sub(r'\D', "", _start_time)  # 20201010
    if dtype=="no-":
        return start_time, today_time, str(datetime.now())[11:16]
    if dtype=="with-":
        return _start_time, _today_time, str(datetime.now())[11:16]
def len_fangzhi(start_time, today_time):
    """
    一般先调用time_start
    :param start_time:'20211031',
    :param today_time: '20211120',
    :return:
    """
    time_ = pro.daily(ts_code='000001.SZ', start_date=start_time, end_date=today_time)['trade_date']  # 20200304
    """
    0     20211119
1     20211118
         ts_code trade_date  open  high   low  close  pre_close  change    pct_chg  vol        amount
    0  000001.SZ   20180718  8.75  8.85  8.69   8.70       8.72   -0.02       -0.23   525152.77   460697.377"""
    # print("{}到{}一共{}天".format(start_time,today_time,len(time_)))#两时间间距15天 #20211030到20211119一共14天
    return len(time_), time_[0], time_[1]

def len_fangzhi_szcode(szcode, start_time, today_time):
    time_ = pro.daily(ts_code=szcode, start_date=start_time, end_date=today_time)['trade_date']  # 20200304
    """ts_code trade_date  open  high   low  close  pre_close  change    pct_chg  vol        amount
    0  000001.SZ   20180718  8.75  8.85  8.69   8.70       8.72   -0.02       -0.23   525152.77   460697.377"""
    return len(time_)
def funcat_time():
    """len_fangzhi(start_time,today_time) 函数+ fc_get(code,start_time,time_0,time_1):部分函数"""
    start_time, today_time, _hour_ = other.time_start()
    len_time, time_0, time_1 = other.len_fangzhi(start_time, today_time)
    _funcat_time = time_0
    print("fc时间", _funcat_time)  # fc时间 20200408
    return _funcat_time, len_time
def time_zhou6_0(dtype="list"):  # 最后一天是否为周六
    start_time, today_time, today_hour = time_start()  # 时间('20200731', '20200820', '16:12')
    time_zhou6 = pro.trade_cal(exchange='', start_date=start_time, end_date=today_time)  # 是否为交易日 ，0为休市 1为开市
    #print(time_zhou6)
    time_zhou6=pd.DataFrame(time_zhou6)
    if dtype=="list":
        return int(time_zhou6.is_open[-1:])
    if dtype=="df":
        return time_zhou6[-1:]
    """    exchange  cal_date  is_open
    0           SSE  20180101        0
    1           SSE  20180102        1
    """
def time_(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        t1 = time.time()
        res = func(*args, **kwargs)
        print("运行时间{}s".format(time.time()-t1))
        return res
    return wrapper
#————————————————————————————————————————————————————————————
def gu_zhengze_sz(code):
    global i_code_temp
    if re.match(r'^6.*', code):
        i_code_temp = code + '.SH'
    if re.match(r'^(0|3).*', code):
        i_code_temp = code + '.SZ'
    return i_code_temp
def re_read_df(df):
    df = df.dropna(axis=0, how='any')
    df['code'] = df['code'].astype(int).astype(str).str.zfill(6)  # 1补缺
    df = df.loc[:, ~df.columns.str.contains('^Unnamed')].drop_duplicates()  # 2去掉Unnamed 并且去重
    df = df[~df['code'].str.startswith('4')]
    df = df[~df['code'].str.startswith('8')]
    df = df[~df['code'].str.startswith('9')]
    return df
def stock_all_list(path_="db_temp/1.数据下载.txt",dtype="1"):
    """
    path_="db_temp/1.数据下载.txt",dtype="1"
    (path_="db_temp/2.his数据下载.txt",dtype="2.1") 读取数据2
    1.返回list
    1.1.返回df
    """
    df = pd.read_csv(path_, encoding="utf-8", index_col=0)
    df=other.re_read_df(df)
    if re.match(r'^(1).*', dtype):
        if dtype=="1":
            return df.code.tolist()
        if  dtype=="1.1":
            return df
    if re.match(r'^(2).*', dtype):
        if dtype=="2":
            return df.code.tolist()
        if  dtype=="2.1":
            return df
#————————————————————————————————————————————————————————————
def _write_console():
    sys.stdout.write("#")
    sys.stdout.flush()
def progress_bar(i,num1=50,num2=160):
    """
    i=0
    for循环需要搭建：
        i+=1
        progress_bar(i,num1=1,num2=2)
    :param i:
    :param num1:
    :param num2:
    :return:
    """
    print("\r", end="")
    print("Download progress: {}%: ".format(i / num1), "▋" * (i //num2), end="")
    sys.stdout.flush()
#————————————————————————————————————————————————————————————
# def V_predict_zhou6():
#     if other.time_zhou6_0() == 0:  # 周末，比例为1
#         bili = 1
#     else:
#         bili = other.V_predict()
#     return bili

def duqu_all(txt_name):
    data_vol = pd.read_csv(txt_name)
    data_vol = data_vol.dropna(axis=0, how='all')  # 2020.10.11修改
    data_vol = data_vol.loc[:, ~data_vol.columns.str.contains('^Unnamed')].drop_duplicates()  # 2去掉Unnamed 并且去重
    data_vol['code'] = data_vol['code'].fillna(0).astype(np.int64)  # 2020.10.11修改
    data_vol['code'] = data_vol['code'].astype(str).str.zfill(6)
    return data_vol

def time_saveandget():
    start_time, today_time, today_hour = other.time_start(days=13)
    trade_cal = pro.trade_cal(exchange='', start_date=start_time, end_date=today_time)
    trade_cal = trade_cal[trade_cal.is_open == 1][-8:].cal_date
    return trade_cal

"""359    20201225
362    20201228
363    20201229
364    20201230
365    20201231
"""


def fc_get(code, start_time, time_0, time_1):
    # code_re=gu_zhengze(code)
    if str(datetime.now())[11:13] <= str(15):
        time_t = time_0
    else:
        time_t = time_1
    S(code)
    T(time_t)
    try:
        # print(HHV(H,10),":::::,日期报错,funcat hhv的问题。")
        print(code[:6], "fc时间{}".format(time_t), str(CLOSE), str(100 * MA(V, 5)), str(100 * MA(V, 30)),
              str(100 * MA(V, 120)), HHV(H, 10), LLV(L, 10), MA(CLOSE, 50))
        return (
        code[:6], "fc时间{}".format(time_t), str(CLOSE), str(100 * MA(V, 5)), str(100 * MA(V, 30)), str(100 * MA(V, 120)),
        HHV(H, 10), LLV(L, 10), MA(CLOSE, 50))
    except:
        # print("KKKK")
        return
        # return (code_re[:6],"fc时间{}".format(time_t),str(CLOSE),str(100*MA(V,5)),str(100*MA(V,30)),str(100*MA(V,120)),HHV(H,10),LLV(L,10),MA(CLOSE,50))






def gaokai(dataframe_):
    data_ = dataframe_
    data_ = data_[(data_["open"] > data_["settlement"]) & (data_["low"] > data_["settlement"])]
    data_o = pd.DataFrame(data_[(data_["o/s"] < 3) & (data_["p/s"] < 15)][
                              ["name_x", "trade", "to", "o/s", "p/s", "industry", "amount_predict", "dxw", "renqi"]])
    return data_o


#     print(data_o)
#     df_bk_pivot = pd.pivot_table(data_o,index=["industry"])
#     print(df_bk_pivot)

def shujujiancha():
    start_time, today_time, today_hour = other.time_start(days=8)
    trade_cal = pro.trade_cal(exchange='', start_date='20200101', end_date=today_time)
    trade_cal = int(trade_cal[-5:].is_open[-1:])
    if trade_cal == 0:
        other.time_start()[1] != other.time_saveandget().tolist()[-1]  # 20210102!=20201231
        print("周末,数据格式检查完毕")
    if trade_cal != 0:
        other.time_start()[1] == other.time_saveandget().tolist()[-1]
        print("工作日,数据格式检查完毕")


#####################################################实验内容
def time_trade_cal_zhou6():
    start_time, today_time, today_hour = other.time_start(days=15)
    trade_cal = pro.trade_cal(exchange='', start_date=start_time, end_date=today_time)
    """exchange	cal_date	is_open
    0	SSE	20210103	0
    1	SSE	20210104	1"""
    trade_cal_zhou6 = trade_cal[trade_cal.is_open == 0]  # 周6
    trade_cal_zhou6["cal_date"] = pd.to_datetime(trade_cal_zhou6.cal_date, format="%Y%m%d")  # 时间中间加杠
    """exchange	cal_date	is_open
    0	SSE	2021-01-03	0
    6	SSE	2021-01-09	0"""
    trade_cal_zhou6.index = pd.to_datetime(trade_cal_zhou6.cal_date)
    trade_cal_zhou6.index.name = "daytime"
    return trade_cal_zhou6.index


"""DatetimeIndex(['2021-01-03', '2021-01-09', '2021-01-10', '2021-01-16',
               '2021-01-17'],
              dtype='datetime64[ns]', name='daytime', freq=None)
daytime              
2021-01-03 00:00:00
2021-01-09 00:00:00
2021-01-10 00:00:00
2021-01-16 00:00:00
2021-01-17 00:00:00
"""


def index_jian_index(minute30_index, time_zhou6_index):
    # minute30_index=minute30(code[1])
    """daytime
    2021-01-05    2
    2021-01-06    3
    2021-01-07    1
    2021-01-08    1
    2021-01-09    0
    2021-01-10    0"""
    #     time_zhou6_index=other.time_trade_cal_zhou6()#每分钟访问60次,改到other gobal中
    for i in time_zhou6_index[:]:
        try:  # a中去掉周六（trade_cal_zhou6.index）  #         print(i)
            minute30_index.drop(index=i, inplace=True)  # concat多个dataframe之后，出现index重复的处理
        except:  # print("在trade_cal_zhou6.index中，不在a中，跳过",i)
            pass

    """daytime
    2021-01-05    2
    2021-01-06    3
    2021-01-07    1
    2021-01-08    1
    2021-01-09    0
    2021-01-10    0

    Freq: D, Name: day, dtype: int64
    2021-01-03 00:00:00
    LLL 2021-01-03 00:00:00
    2021-01-09 00:00:00
    2021-01-10 00:00:00
    daytime
    2021-01-05    2
    2021-01-06    3
    2021-01-07    1
    2021-01-08    1
    """
    #     print(minute30_index.values)#[2 0 3 1 5 3 5 2 4 1]
    return minute30_index.values


def minute30(code, datalen=200, daytime=120):  # SZ000001
    # 数据获得
    time.sleep(1)  # 防绊1S
    url_str = 'http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol={}&scale=30&ma=25&datalen={}'.format(
        code, datalen)
    """最近二十天左右的每5分钟数据 
    http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=sz000001&scale=5&ma=5&datalen=1023 
    （参数：股票编号、分钟间隔（5、15、30、60）、均值（5、10、15、20、25）、查询个数点（最大值242））"""
    r = requests.get(url_str)
    if r.status_code == 456:
        print("被网站禁止，检查time.sleep(1)")
    r_json = r.json()
    r = pd.DataFrame(r_json, dtype=np.float)  # r["volume"]=r.volume.astype(np.float64)  #2020.10.11修改
    # 数据预处理
    r.index = pd.to_datetime(r.day)
    r.index.name = "daytime"
    r['minute30_v{}'.format(daytime)] = tb.MA(np.array(r.volume), timeperiod=daytime)
    r["r_ture1"] = r.volume > r.minute30_v120
    r["r_ture1_shift1"] = r["r_ture1"].shift(1)
    r["r_ture"] = r.r_ture1 & r.r_ture1_shift1
    r["r_2bei"] = r.volume > 2 * r.minute30_v120
    return r


"""<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 200 entries, 2020-12-15 10:00:00 to 2021-01-19 15:00:00
Data columns (total 13 columns):
close             200 non-null float64
day               200 non-null object
high              200 non-null float64
low               200 non-null float64
ma_price25        200 non-null float64
ma_volume25       200 non-null float64
open              200 non-null float64
volume            200 non-null float64
minute30_v120     81 non-null float64
r_ture1           200 non-null bool
r_ture1_shift1    199 non-null object
r_ture            200 non-null bool
r_2bei            200 non-null bool
dtypes: bool(3), float64(8), object(2)"""


def time_tolist(r, time_zhou6_index):  # other_30min=other.minute30(szcode,)
    r_ture1day = r[r['r_ture1'].isin([1])]  # pandas获取某个数据的行号 已知列名：df[df['列名'].isin([相应的值])]
    r_day_all = r.day.resample('D').count()[-15:]
    #     print(r_day_all)
    """daytime
    2021-01-05    8
    2021-01-06    8
    2021-01-07    8
    2021-01-08    8
    2021-01-09    0
    2021-01-10    0
    2021-01-11    8
    2021-01-12    8
    2021-01-13    8
    2021-01-14    8
    2021-01-15    8
    2021-01-16    0
    2021-01-17    0
    2021-01-18    8
    2021-01-19    8"""
    other_ = other.index_jian_index(r_day_all, time_zhou6_index)
    #     print(r_ture1day.day.resample('D').count()[-15:])
    if 0 in set(other_):  # 去掉带list 带0[8. 0. 8. 8. 8. 8. 8. 8. 8. 8. 8.]
        return
    return other_  # [8. 8. 8. 8. 8. 8. 8. 8. 8. 8. 8.]


def time_tolist_0():
    # code=["sh601890","sh600111","sz300224","SZ000590"]
    time_zhou6_index = other.time_trade_cal_zhou6()  # 每分钟访问60次,获得周6 数据
    data_gp_all = other.get_szcode()  # 便利所有股票
    x_list = []
    for szcode in random.sample(data_gp_all.szcode.tolist(), 3):
        #     print(szcode)
        other_30min = other.minute30(szcode)  # [8. 8. 0  0  8. 8. 8. 8. 8. 8. 8. 8. 8.]
        x = other.time_tolist(other_30min, time_zhou6_index)  # [8. 8. 8. 8. 8. 8. 8. 8. 8. 8. 8.]
        if x is None:
            print("过滤None")
        else:
            x_list.append(len(x))
    # print(x_list)#[array([8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]), array([8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]), array([8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8])]

    # 查找列表中的重复元素
    x_list_most_set = other.find_duplicate(x_list)
    x_list_most = list(x_list_most_set)
    #     print(np.zeros(x_list_most)) #[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
    return np.zeros(x_list_most)


def get_szcode():
    data_gp_all = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
    data_gp_all = pd.concat(
        [data_gp_all, data_gp_all["ts_code"].str.split('.', expand=True).rename(columns={0: 'code', 1: 'sz代码'})],
        axis=1)
    data_gp_all["szcode"] = data_gp_all.sz代码.map(str) + data_gp_all.code.map(str)
    """ts_code	symbol	name	area	industry	list_date	code	sz代码	szcode
    0	000001.SZ	000001	平安银行	深圳	银行	19910403	000001	SZ	SZ000001"""
    return data_gp_all


def find_duplicate(arr):
    set_arr = set()
    dup = set()
    for x in arr:
        if x not in set_arr:
            set_arr.add(x)
        else:
            dup.add(x)
    return dup

if __name__ == '__main__':
    print(funcat_time())
"""
# 查找列表中的重复元素
def find_duplicate(arr):
    set_arr = set()
    dup = set()
    for x in arr:
        if x not in set_arr:
            set_arr.add(x)
        else:
            dup.add(x)
    return dup


if __name__ == '__main__':
    array = [1, 2, 3, 4, 4, 4, 4]
    print(find_duplicate(array))     #4 """